package com.costaccounting.feesys.service.impl;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.security.cert.TrustAnchor;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import com.costaccounting.base.domain.ZsCategory;
import com.costaccounting.base.service.IZsCategoryService;
import com.costaccounting.common.constant.UserConstants;
import com.costaccounting.common.core.domain.AjaxResult;
import com.costaccounting.common.utils.DateUtils;
import com.costaccounting.common.utils.SecurityUtils;
import com.costaccounting.common.utils.StringUtils;
import com.costaccounting.feesys.domain.ZsFee;
import com.costaccounting.feesys.service.IZsFeeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.costaccounting.feesys.mapper.ZsCategoryPercentageMapper;
import com.costaccounting.feesys.domain.ZsCategoryPercentage;
import com.costaccounting.feesys.service.IZsCategoryPercentageService;

/**
 * 分类占比Service业务层处理
 * 
 * @author ruoyi
 * @date 2021-11-26
 */
@Service
public class ZsCategoryPercentageServiceImpl implements IZsCategoryPercentageService 
{
    @Autowired
    private ZsCategoryPercentageMapper zsCategoryPercentageMapper;
    @Autowired
    private IZsFeeService feeService;
    @Autowired
    private IZsCategoryService categoryService;
    /**
     * 查询分类占比
     * 
     * @param id 分类占比主键
     * @return 分类占比
     */
    @Override
    public ZsCategoryPercentage selectZsCategoryPercentageById(Long id)
    {
        return zsCategoryPercentageMapper.selectZsCategoryPercentageById(id);
    }

    /**
     * 查询分类占比列表
     * 
     * @param zsCategoryPercentage 分类占比
     * @return 分类占比
     */
    @Override
    public List<ZsCategoryPercentage> selectZsCategoryPercentageList(ZsCategoryPercentage zsCategoryPercentage)
    {
        return zsCategoryPercentageMapper.selectZsCategoryPercentageList(zsCategoryPercentage);
    }

    /**
     * 新增分类占比
     * 
     * @param zsCategoryPercentage 分类占比
     * @return 结果
     */
    @Override
    public int insertZsCategoryPercentage(ZsCategoryPercentage zsCategoryPercentage)
    {
        zsCategoryPercentage.setCreateTime(DateUtils.getNowDate());
        return zsCategoryPercentageMapper.insertZsCategoryPercentage(zsCategoryPercentage);
    }

    /**
     * 修改分类占比
     * 
     * @param zsCategoryPercentage 分类占比
     * @return 结果
     */
    @Override
    public int updateZsCategoryPercentage(ZsCategoryPercentage zsCategoryPercentage)
    {
        zsCategoryPercentage.setUpdateTime(DateUtils.getNowDate());
        return zsCategoryPercentageMapper.updateZsCategoryPercentage(zsCategoryPercentage);
    }

    /**
     * 批量删除分类占比
     * 
     * @param ids 需要删除的分类占比主键
     * @return 结果
     */
    @Override
    public int deleteZsCategoryPercentageByIds(Long[] ids)
    {
        return zsCategoryPercentageMapper.deleteZsCategoryPercentageByIds(ids);
    }

    /**
     * 删除分类占比信息
     * 
     * @param id 分类占比主键
     * @return 结果
     */
    @Override
    public int deleteZsCategoryPercentageById(Long id)
    {
        return zsCategoryPercentageMapper.deleteZsCategoryPercentageById(id);
    }

    @Override
    public AjaxResult syncCategoryPercentage(ZsFee zsFee) {
        //占比：获取当前分类对应费用类型的占比，取出当前分类的相应金额，再取出其父类对应的相应金额
        //是否预警：当前分类的，人材机，中的实际费用大于成本预测，或大于工程预算的

        //占比实现，1.取出当前分类以及父分类所有的费用明细
        ZsCategory category = categoryService.selectZsCategoryById(zsFee.getCategoryId());
        //获取分类路径，取第一级路径下的所有末级分类对应的费用
        String ancestors = category.getAncestors();
        String firstCategoryId = ancestors.split(",")[0];
        ZsFee feeWhere=new ZsFee();
        feeWhere.setAncestors(firstCategoryId);
        List<ZsFee> allFeeList = feeService.selectZsFeeList(feeWhere);
        List<String> categoryIdPath = convert2List(ancestors);
        if(StringUtils.isNotEmpty(allFeeList)){
            BigDecimal preAmount=new BigDecimal(0);
            BigDecimal preAmount2=new BigDecimal(0);
            BigDecimal preAmount3=new BigDecimal(0);
            for (String categoryId : categoryIdPath) {
                //取出包含这个分类，并且费用类型一致的费用明细
                List<ZsFee> collect = allFeeList.stream().filter(f -> convert2List(f.getAncestors()).contains(categoryId) && f.getFeeType().equals(zsFee.getFeeType())).collect(Collectors.toList());
                //再取出具体的人材机的费用
                if(StringUtils.isNotEmpty(collect)){
                    BigDecimal totalAmount=new BigDecimal(0);
                    BigDecimal totalAmount2=new BigDecimal(0);
                    BigDecimal totalAmount3=new BigDecimal(0);
                    BigDecimal zb=new BigDecimal("1");
                    BigDecimal zb2=new BigDecimal("1");
                    BigDecimal zb3=new BigDecimal("1");

                    if(!isBigDecimalNull(zsFee.getLaborTotal())){
                        totalAmount=collect.stream().filter(f -> f.getLaborTotal() != null).map(ZsFee::getLaborTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
                        if(preAmount.compareTo(new BigDecimal(0))!=0){
                            zb = totalAmount.divide(preAmount,2,RoundingMode.HALF_UP);
                        }
                        insertAllPercentage(zsFee,UserConstants.FEE_TYPE_LABOR,categoryId,totalAmount,zb);
                        preAmount=totalAmount;
                    }
                    if(!isBigDecimalNull(zsFee.getMaterialTotal())){
                        totalAmount2=collect.stream().filter(f -> f.getMaterialTotal() != null).map(ZsFee::getMaterialTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
                        if(preAmount2.compareTo(new BigDecimal(0))!=0){
                            zb2 = totalAmount2.divide(preAmount2,2,RoundingMode.HALF_UP);
                        }
                        insertAllPercentage(zsFee,UserConstants.FEE_TYPE_MATERIAL,categoryId,totalAmount2,zb2);
                        preAmount2=totalAmount2;
                    }
                    if(!isBigDecimalNull(zsFee.getMachineryTotal())){
                        totalAmount3=collect.stream().filter(f -> f.getMachineryTotal() != null).map(ZsFee::getMachineryTotal).reduce(BigDecimal.ZERO, BigDecimal::add);
                        if(preAmount3.compareTo(new BigDecimal(0))!=0){
                            zb3 = totalAmount3.divide(preAmount3,2,RoundingMode.HALF_UP);
                        }
                        insertAllPercentage(zsFee,UserConstants.FEE_TYPE_MACHINERY,categoryId,totalAmount3,zb3);
                        preAmount3=totalAmount3;
                    }
                }
            }
        }
        return AjaxResult.success();
    }

    void insertAllPercentage(ZsFee zsFee,String feeCategory,String categoryId,BigDecimal totalAmount,BigDecimal zb){
        ZsCategoryPercentage zsCategoryPercentage=new ZsCategoryPercentage();
        zsCategoryPercentage.setCategoryId(Long.parseLong(categoryId));
        zsCategoryPercentage.setItemId(zsFee.getItemId());
        zsCategoryPercentage.setFeeType(zsFee.getFeeType());
        //先判断该目录是否已经添加过
        ZsCategoryPercentage where=new ZsCategoryPercentage();
        where.setItemId(zsCategoryPercentage.getItemId());
        where.setCategoryId(Long.parseLong(categoryId));
        where.setFeeType(zsFee.getFeeType());
        where.setFeeCategory(feeCategory);
        List<ZsCategoryPercentage> zsCategoryPercentages = this.selectZsCategoryPercentageList(where);
        if(StringUtils.isNotEmpty(zsCategoryPercentages)){
            ZsCategoryPercentage zsCategoryPercentage1 = zsCategoryPercentages.get(0);
            zsCategoryPercentage1.setPercentage(zb);
            zsCategoryPercentage1.setAmount(totalAmount);
            this.updateZsCategoryPercentage(zsCategoryPercentage1);
        }else{
            zsCategoryPercentage.setPercentage(zb);
            zsCategoryPercentage.setAmount(totalAmount);
            zsCategoryPercentage.setCreateTime(new Date());
            zsCategoryPercentage.setCreateBy(SecurityUtils.getUsername());
            zsCategoryPercentage.setFeeCategory(feeCategory);
            this.insertZsCategoryPercentage(zsCategoryPercentage);
        }
    }

    boolean isBigDecimalNull(BigDecimal val){
        if(val!=null&&val.compareTo(new BigDecimal(0))!=0){
            return false;
        }else{
            return true;
        }
    }

    List<String> convert2List(String str){
        String[] split = str.split(",");
        List<String> result=new ArrayList<>();
        for (int i = 0; i < split.length; i++) {
            result.add(split[i]);
        }
        return result;
    }
}
